`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: ZJLAB
// Engineer: 
// 
// Create Date: 2021/04/25 09:21:10
// Design Name: lixiangdi
// Module Name: axi_master_with_fifo
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////

module axi_master_with_fifo#(
    parameter   axi_data_width          =   512         ,//Support 32,64,128,256,512 
    parameter   fifo_memory_type        =   "block"     ,
    parameter   fifo_memory_deep        =   512         ,   
    parameter   d_cnt_width             =   9            //fifo_data_count_width:2^d_cnt_width = fifo_memory_deep
)
(
    input   wire                            sys_clk         ,
    input   wire                            sys_rst         ,
    input   wire                            start_axi       ,//start axi: pulse.
    input   wire                            read_or_write   ,//0:read 1:writer
                
    input   wire    [31:0]                  address         ,   
    input   wire    [7:0]                   burst_length    ,
    input   wire    [2:0]                   burst_size      ,
    input   wire    [1:0]                   increment_burst ,//01 = incrementing addresses, 00 = fixed addresses
                
    output  wire                            busy_wr         ,//1:busy
    output  wire                            error_wr        ,//1:error
    output  wire                            done_wr         ,//1:complete
                
    output  wire                            busy_rd         ,//1:busy
    output  wire                            done_rd         ,
    output  wire                            error_rd        ,           
//---------------------data interfacec-------------------
//  data input
    input   wire    [axi_data_width-1:0]    din             ,//
    input   wire                            din_valid   ,//
//  data_in fifo            
    output  wire                            write_fifo_full         ,
    output  wire    [d_cnt_width-1:0]       write_fifo_data_count   ,
    output  wire                            write_fifo_empty        ,
        
//  data output 
    output  wire    [axi_data_width-1:0]    dout            ,//
    output  wire                            dout_valid      ,//
//  data_out fifo                   
    output  wire                            read_fifo_full          ,
    output  wire    [d_cnt_width-1:0]       read_fifo_data_count    ,
    output  wire                            read_fifo_empty     ,
//---------------------axi interfacec-------------------
    input   wire                m_axi_aclk      ,               
    input   wire                m_axi_reset     ,
//  AXI4 Read Address Channel   
    input   wire                        m_axi_arready   ,               
    output  wire                        m_axi_arvalid   ,           
    output  wire    [31:0]              m_axi_araddr    ,           
    output  wire    [3:0]               m_axi_arid      ,           
    output  wire    [7:0]               m_axi_arlen     ,           
    output  wire    [2:0]               m_axi_arsize    ,           
    output  wire    [1:0]               m_axi_arburst   ,           
    output  wire                        m_axi_arlock    ,        
    output  wire    [3:0]               m_axi_arcache   ,           
    output  wire    [2:0]               m_axi_arprot    ,           
    output  wire    [3:0]               m_axi_arqos     ,           
    output  wire    [3:0]               m_axi_arregion  ,           
//  outAXI4 Read Data Channel
    output  wire                        m_axi_rready    ,          
    input   wire                        m_axi_rvalid    ,       
    input   wire    [axi_data_width-1:0]    m_axi_rdata     ,       
    input   wire    [1:0]               m_axi_rresp     ,       
    input   wire    [3:0]               m_axi_rid       ,       
    input   wire                        m_axi_rlast     ,           
//  AXI4 Write Address Channel
    input   wire                        m_axi_awready   ,           
    output  wire                        m_axi_awvalid   ,        
    output  wire    [31:0]              m_axi_awaddr    ,       
    output  wire    [3:0]               m_axi_awid      ,       
    output  wire    [7:0]               m_axi_awlen     ,       
    output  wire    [2:0]               m_axi_awsize    ,       
    output  wire    [1:0]               m_axi_awburst   ,       
    output  wire                        m_axi_awlock    ,       
    output  wire    [3:0]               m_axi_awcache   ,       
    output  wire    [2:0]               m_axi_awprot    ,       
    output  wire    [3:0]               m_axi_awqos     ,       
    output  wire    [3:0]               m_axi_awregion  ,       
//  AXI4 Write Data Channel
    input   wire                        m_axi_wready    ,           
    output  wire                        m_axi_wvalid    ,        
    output  wire    [3:0]               m_axi_wid       ,       
    output  wire    [axi_data_width-1:0]    m_axi_wdata     ,        
    output  wire    [axi_data_width/8-1:0]              m_axi_wstrb     ,        
    output  wire                        m_axi_wlast     ,        
//  AXI4 Write Response Channel
    output  wire                        m_axi_bready    ,           
    input   wire                        m_axi_bvalid    ,        
    input   wire    [1:0]               m_axi_bresp     ,        
    input   wire    [3:0]               m_axi_bid             
    );
        
    wire    [axi_data_width-1:0]        axi_data_wr;    
    wire                                axi_data_wr_valid;          
    wire                                axi_data_wr_ready;  

    wire    [axi_data_width-1:0]        axi_data_rd;    
    wire                                axi_data_rd_valid;          
    wire                                axi_data_rd_ready;  

    
    fifo_manager#(  
        .axi_data_width         (axi_data_width                 ),//Support 32,64,128,256,512 
        .fifo_memory_type       (fifo_memory_type               ),
        .fifo_memory_deep       (fifo_memory_deep                   ),      
        .d_cnt_width            (d_cnt_width            )    //fifo_data_count_width:2^d_cnt_width = fifo_memory_deep
    
    )fifo_manager(
        .sys_clk             (sys_clk               ),
        .sys_rst             (sys_rst               ),
        .wr_fifo_in          (din                   ),
        .wr_fifo_en          (din_valid             ),
        .wr_fifo_full        (write_fifo_full       ),  
        .wr_fifo_data_count  (write_fifo_data_count ),
        .wr_fifo_empty       (write_fifo_empty      ), 
        .wr_out              (axi_data_wr           ),
        .wr_out_valid        (axi_data_wr_valid     ),
        .wr_out_ready        (axi_data_wr_ready     ),
        .rd_fifo_in          (axi_data_rd           ),
        .rd_fifo_en          (axi_data_rd_valid     ),
        .rd_fifo_ready       (axi_data_rd_ready     ),
        .rd_fifo_full        (read_fifo_full        ),
        .rd_fifo_data_count  (read_fifo_data_count  ),
        .rd_fifo_empty       (read_fifo_empty       ),  
        .rd_out              (dout                  ),
        .rd_out_valid        (dout_valid            )
    );  
    
    axi_master #(
        .axi_data_width         (axi_data_width                 )
    )
    axi_master_u0(
        .sys_clk             (sys_clk               ),
        .sys_rst             (sys_rst               ),
        .start_axi           (start_axi             ),
        .read_or_write       (read_or_write         ),
        .address             (address               ),
        .burst_length        (burst_length          ),
        .burst_size          (burst_size            ), 
        .increment_burst     (increment_burst       ),
        .busy_wr             (busy_wr               ),
        .busy_rd             (busy_rd               ),
        .done_wr             (done_wr               ),
        .done_rd             (done_rd               ),
        .error_wr            (error_wr              ),
        .error_rd            (error_rd              ),
        .din                 (axi_data_wr           ),
        .din_valid           (axi_data_wr_valid     ),
        .din_ready           (axi_data_wr_ready     ),
        .dout                (axi_data_rd           ),
        .dout_valid          (axi_data_rd_valid     ),
        .dout_ready          (axi_data_rd_ready     ),
        .m_axi_arready       (m_axi_arready         ),
        .m_axi_arvalid       (m_axi_arvalid         ),
        .m_axi_araddr        (m_axi_araddr          ),
        .m_axi_arid          (m_axi_arid            ),
        .m_axi_arlen         (m_axi_arlen           ),
        .m_axi_arsize        (m_axi_arsize          ),
        .m_axi_arburst       (m_axi_arburst         ),
        .m_axi_arlock        (m_axi_arlock          ),
        .m_axi_arcache       (m_axi_arcache         ),
        .m_axi_arprot        (m_axi_arprot          ),
        .m_axi_arqos         (m_axi_arqos           ),
        .m_axi_arregion      (m_axi_arregion        ),
        .m_axi_rready        (m_axi_rready          ),
        .m_axi_rvalid        (m_axi_rvalid          ),
        .m_axi_rdata         (m_axi_rdata           ),
        .m_axi_rresp         (m_axi_rresp           ),
        .m_axi_rid           (m_axi_rid             ),
        .m_axi_rlast         (m_axi_rlast           ),
        .m_axi_awready       (m_axi_awready         ),
        .m_axi_awvalid       (m_axi_awvalid         ),
        .m_axi_awaddr        (m_axi_awaddr          ),
        .m_axi_awid          (m_axi_awid            ),
        .m_axi_awlen         (m_axi_awlen           ),
        .m_axi_awsize        (m_axi_awsize          ),
        .m_axi_awburst       (m_axi_awburst         ),
        .m_axi_awlock        (m_axi_awlock          ),
        .m_axi_awcache       (m_axi_awcache         ),
        .m_axi_awprot        (m_axi_awprot          ),
        .m_axi_awqos         (m_axi_awqos           ),
        .m_axi_awregion      (m_axi_awregion        ),
        .m_axi_wready        (m_axi_wready          ),
        .m_axi_wvalid        (m_axi_wvalid          ),
        .m_axi_wid           (m_axi_wid             ),
        .m_axi_wdata         (m_axi_wdata           ),
        .m_axi_wstrb         (m_axi_wstrb           ),
        .m_axi_wlast         (m_axi_wlast           ),
        .m_axi_bready        (m_axi_bready          ),
        .m_axi_bvalid        (m_axi_bvalid          ),
        .m_axi_bresp         (m_axi_bresp           ),
        .m_axi_bid           (m_axi_bid             )
    ); 
    
    
    localparam  fifo_d_cnt_width = clogb2(fifo_memory_deep);
    
    function integer clogb2 (input integer bit_depth);
        begin
            for(clogb2=0; bit_depth>0; clogb2=clogb2+1)
            bit_depth = bit_depth>>1;
        end
    endfunction 

    
    
endmodule
